//
// Created on 2024/2/17.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef AVCODEC_SAMPLE_MULTI_SURFACE4_H
#define AVCODEC_SAMPLE_MULTI_SURFACE4_H

#include <bits/alltypes.h>
#include <mutex>
#include <memory>
#include <atomic>
#include <thread>
#include <unistd.h>
#include "capbilities/base/video_sample_base.h"
#include "video_decoder.h"
#include "capbilities/data_producer/demuxer/demuxer.h"
#include "sample_info.h"
#include "plugin_manager.h"

class MultiSurface_4 : public VideoSampleBase {
public:
    //    static MultiSurface& GetInstance()
    //    {
    //        static MultiSurface multiSurface_;
    //        return multiSurface_;
    //    }

    int32_t Create(SampleInfo &sampleInfo) override;
    int32_t Start() override;
    int32_t Stop();
    int32_t Pause();
    int32_t Play();
    int32_t VideoSeek(int64_t currentTime);
    int32_t Loop(bool loopFlag);
    int32_t SetSurface(const std::string id);
    int32_t GetWindowManager(const std::string id);
    int32_t SetWindowManager(const std::string id);
    int32_t SetSurfaceNative(bool isAuto, int32_t sampleId);

    bool isVertical = false;
    std::atomic<bool> isStarted{false};
    std::atomic<bool> autoSwitchSurface{false};
    int32_t sampleId = -1;

private:
    void DecInputThread();
    void DecOutputThread();
    void Release() override;

    std::unique_ptr<VideoDecoder> videoDecoder_ = nullptr;

    std::mutex mutex_;
    std::atomic<bool> isLoop{false};
    std::atomic<bool> isPause{false};
    std::unique_ptr<std::thread> decInputThread_ = nullptr;
    std::unique_ptr<std::thread> decOutputThread_ = nullptr;
    std::unique_ptr<std::thread> releaseThread_ = nullptr;
    SampleInfo sampleInfo_;
    static constexpr int64_t MILLISECONDS = 1000;
    static constexpr int64_t MICROSECOND = 1000000;

    bool switchSurfaceFlag = false;

private:
    int32_t id;
    static int32_t maxNumOfMultiSurface;
    static std::vector<MultiSurface_4 *> multiSurfaceList;
    MultiSurface_4(){};
    MultiSurface_4(int32_t id);
    ~MultiSurface_4();

public:
    static void SetMaxNum(int32_t num);
    static MultiSurface_4 *getInstance(int32_t id);
    static void releaseInstance();
};

#endif // AVCODEC_SAMPLE_MULTI_SURFACE4_H
